/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package analiseSintatica.Regras.Comandos;

import AnaliseLexicaFinal.EstruturaDeDados.LinkToken;
import analiseSemantica.Tipos.TiposSemanticos;
import analiseSintatica.ErroSintaticoException;
import analiseSintatica.Regras.Declaracoes.RegraDeclaracao;
import analiseSintatica.Regras.Expressoes.RegraAtribuicao;
import analiseSintatica.Regras.Expressoes.RegraIncremento;
import analiseSintatica.Regras.Expressoes.RegraOpIncremento;
import analiseSintatica.Regras.Funcao.RegraChamadaFuncao;
import analiseSintatica.Regras.Regra;
import java.util.LinkedList;


/**
 *
 * @author Ivo Romário
 */
public class RegraInstrucao extends Regra{


    protected static Regra instancia;

    protected String estrutura = "<declaracao>|<cmd>|<atribuicao>';'|<incremento>';'|<chamada_funcao>';'";

    
    /**
     * Construtor privado necessario ao singleton
     */
    public RegraInstrucao(){

    }

    /**
     * Retorna a unica instancia dessa classe.
     * @return
     */
    public static RegraInstrucao getInstance() {
        if (instancia == null) {
            instancia = new RegraInstrucao();
        }
        return (RegraInstrucao) instancia;
    }

    

    @Override
    public TiposSemanticos analisar(LinkedList<LinkToken> listaTokens) throws ErroSintaticoException {

        TiposSemanticos tipos = null;

        if(listaContem(RegraCmd.getInstance().getPrimeiro(), listaTokens.getFirst())){

            tipos = RegraCmd.getInstance().analisar(listaTokens);

        }else if(listaContem(RegraIncremento.getInstance().getPrimeiro(), listaTokens.getFirst())&&
                listaContem(RegraOpIncremento.getInstance().getPrimeiro(), listaTokens.get(1)))
        {
            RegraIncremento.getInstance().analisar(listaTokens);
            reconheceLexema(listaTokens, "delimitador", ";", estrutura);
        }else if(listaContem(RegraChamadaFuncao.getInstance().getPrimeiro(), listaTokens.getFirst()) &&
                listaTokens.get(1).getLexema().equals("(")){

            RegraChamadaFuncao.getInstance().analisar(listaTokens);
            reconheceLexema(listaTokens, "delimitador", ";", estrutura);
        }else if(listaContem(RegraDeclaracao.getInstance().getPrimeiro(), listaTokens.getFirst()) &&
        		(listaTokens.get(1).getLexema().equals("*") || listaTokens.get(1).getToken().equals("identificador"))){
        	RegraDeclaracao.getInstance().analisar(listaTokens);
        }else{
        	RegraAtribuicao.getInstance().analisar(listaTokens);
        	reconheceLexema(listaTokens, "delimitador", ";", estrutura);
        }

         return tipos;
        
    }

    @Override
    protected void setPrimeiro() {
        this.primeiro = RegraDeclaracao.getInstance().getPrimeiro();
        this.primeiro = getUniao(this.primeiro, RegraCmd.getInstance().getPrimeiro());
        this.primeiro = getUniao(this.primeiro, RegraAtribuicao.getInstance().getPrimeiro());
        this.primeiro = getUniao(this.primeiro, RegraIncremento.getInstance().getPrimeiro());
        this.primeiro = getUniao(this.primeiro, RegraChamadaFuncao.getInstance().getPrimeiro());
    }
}
